import fs from "fs";
import { Node } from "./genNode";
import { getFileKeyValue } from "./getFileKeyValues";
import { insertStr, isComma } from "./insertStr";
import { errlogs, logs } from "./main";
import { getOptions } from "./options";
import { transform } from "./req";

const { from, to, lazy, targets, requestInterval, requestWordsNumber } =
  getOptions();

interface Res {
  from: string;
  to: string;
  trans_result: { src: string; dst: string }[];
}

//生成切片任务批次
const genTaskSlice = (values: string[]) => {
  let len = 0;
  let lastIndex = 0;
  const strSlice: string[] = [];
  values.forEach((s, i) => {
    if (i === values.length - 1) {
      return strSlice.push(values.slice(lastIndex, i + 1).join("\n"));
    }
    if (len + 1 + s.length <= (requestWordsNumber || 3000)) {
      len += s.length + 1;
    }
    if (len + 1 + s.length > (requestWordsNumber || 3000)) {
      len = 0;
      strSlice.push(values.slice(lastIndex, i + 1).join("\n"));
      lastIndex = i + 1;
    }
  });
  return strSlice;
};

interface Param {
  importPath: string;
  outerPath?: string;
  lang?: string;
  node?: Node;
  rootKeys?: string[];
  rootValues?: string[];
}

export const handleContent = (param: Param) => {
  const { node, importPath, outerPath, lang, rootValues, rootKeys } = param;
  let oldContent = "";
  //翻译目标文件是否存在
  let fileIsExist = true;
  try {
    oldContent = fs.readFileSync(importPath, "utf-8");
  } catch (error) {
    oldContent = fs.readFileSync(node?.importPath as string, "utf-8");
    fileIsExist = false;
  }

  //keys是要翻译的key值,values是需要翻译的语言,err是解析错误的地方如果存在就不继续翻译
  let [keys, values, err] = getFileKeyValue({ content: oldContent });
  //准备删除的标记
  const del = Symbol("delete");
  //如果文件是已经存在的并且当前是懒翻译状态则找出目标文件和源文件key的差集翻译
  if (fileIsExist && rootKeys && rootValues) {
    for (let i = 0; i < rootKeys.length; i++) {
      const index = keys.indexOf(rootKeys[i]);
      if (index !== -1) {
        //标记为删除状态
        keys[index] = del as any;
        values[index] = del as any;
      } else {
        keys.push(rootKeys[i]);
        values.push(rootValues[i]);
      }
    }
    for (let i = 0; i < keys.length; i++) {
      if (keys[i] !== (del as any)) {
        const index = rootKeys.indexOf(keys[i]);
        if (index === -1) {
          keys[i] = del as any;
          values[i] = del as any;
        }
      }
    }

    //删除标记的值
    keys = keys.filter((t) => t !== (del as any));
    values = values.filter((t) => t !== (del as any));
  }

  return async () => {
    // return Promise.resolve("");
    try {
      let count = 0; //翻译总数
      const apiNowStart = Date.now();
      if (err) throw err;
      //#region 请求切片处理,一次接口翻译数量有上限
      const tasks = genTaskSlice(values);
      let newContent = oldContent;
      if (isComma(newContent)) {
        newContent = insertStr(newContent, ",\n");
      }
      async function* fun() {
        for (let i = 0; i < tasks.length; i++) {
          const {
            data: { trans_result },
          } = (await transform(tasks[i], lang || (to as string), from)) as {
            data: Res;
          };

          trans_result.forEach((cd) => {
            let key = "";
            values.find((s, i) => {
              if (s === cd.src) {
                return (key = keys[i]);
              }
            });
            if (fileIsExist) {
              const part = `  '${key}':'${cd.dst}',\n`;
              newContent = insertStr(newContent, part);
            } else {
              //replce替换是从整个字符串的第一个开始往后匹配,如果遇到不同的key用的同一语言就翻译错了
              //keys和values以及接口返回值长度和顺序一致在这用key值做分隔符,将整个国际化文件分成两半
              //key不会重复因此可以直接从下半部分开始替换这样replace永远只会替换正确的
              const str1 = newContent.slice(0, newContent.indexOf(key));
              let str2 = newContent.slice(newContent.indexOf(key));
              str2 = str2.replace(cd.src, cd.dst);
              newContent = str1 + str2;
              //记录翻译数量(大致数量)
            }
            count += cd.dst.length;
          });
          yield;
        }
      }
      const gener = fun();
      do {
        const { done, value } = await gener.next();
        if (done) {
          break;
        }
      } while (1);
      //#endregion
      const apiNowEnd = Date.now();
      const fileNowStart = Date.now();
      if (lazy && targets?.length) {
        fs.writeFileSync(importPath, newContent, "utf-8");
      } else {
        fs.writeFileSync(outerPath as string, newContent, "utf-8");
      }
      const fileNowEnd = Date.now();
      const apiTime = (apiNowEnd - apiNowStart) / 1000;
      const fileTime = (fileNowEnd - fileNowStart) / 1000;
      const str = `${
        lazy ? importPath : outerPath
      }\t\t文件写入成功\n 接口耗时${apiTime}秒\t写入文件耗时${
        (fileNowEnd - apiNowStart) / 1000
      }秒\t总耗时${fileTime}秒\t共计翻译数量: ${count}\n`;
      logs.push(str);
      if (node) {
        node.apiTime = apiTime;
        node.fileTime = fileTime;
        node.done = true;
        node.allTime = count;
        node.msg = `文件翻译成成功! 共翻译数量: ${count}`;
      }
      return str;
    } catch (error) {
      const str = `${
        lazy ? importPath : outerPath
      }\t\t文件写入失败!!! 错误信息: ${error}}`;
      errlogs.push(str);
      return str;
    }
  };
};
